/**
 * 
 * @author Isaac
 *
 *	This class is the main class of the server
 */

package presentation;

import java.awt.BorderLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.StringTokenizer;
import java.util.Vector;

import javax.swing.JButton;
import javax.swing.JFrame;

import domain.Debug;

public class GuiController extends Thread
{

	private static final long SLEEP_TIME_BEFORE_EXIT = 2000;
	private Object lock = new Object();
	private boolean doneGame = false;

	public GuiController(){

	}
	@Override
	public void run(){
		try {
			//Mymain.main(null);

			DatagramSocket serverSocket = new DatagramSocket(9876); 
			System.out.println("Server is on");

			while(! done() ) 
			{ 
				byte[] receiveData = new byte[1024]; 
				byte[] sendData  = new byte[1024]; 		
				DatagramPacket receivePacket = 
					new DatagramPacket(receiveData, receiveData.length); 
				serverSocket.receive(receivePacket); 
				String sentence = new String(receivePacket.getData());
				if (sentence.contains("stop")){
					//Debug.println("got stop message");

					//GuiController.bmain.stop();
					try {
						Thread.sleep(SLEEP_TIME_BEFORE_EXIT);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					System.exit(0);
					break;
				}

				sentence=parseInput(sentence);
				InetAddress IPAddress = receivePacket.getAddress(); 

				int port = receivePacket.getPort(); 

				String capitalizedSentence = sentence.toUpperCase(); 

				sendData = capitalizedSentence.getBytes(); 

				DatagramPacket sendPacket = 
					new DatagramPacket(sendData, sendData.length, IPAddress, 
							port); 

				serverSocket.send(sendPacket); 
			}

			Debug.println("Server stoped ...");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}


	public void stopTheGame(){
		synchronized (lock) {
			doneGame = true;
			JFrame exitFraem = new JFrame();
			JButton exitButton = new JButton("<html>Press me to Exit<br> &nbsp&nbsp&nbsp Or Wait ...</html>");

			frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
			frame1.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
			exitFraem.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
			exitButton.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					//cleanUp();
					System.exit(0);
				}
			});
			exitButton.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					//cleanUp();
					System.exit(0);
				}
			});

			exitFraem.add(exitButton);
			exitFraem.setSize(150, 80);
			exitFraem.setLocation(frame.getLocation().x + frame.getSize().width , frame.getLocation().y);
			exitFraem.validate();
			exitFraem.setVisible(true);
			exitFraem.setAlwaysOnTop(true);

			try {
				Thread.sleep(SLEEP_TIME_BEFORE_EXIT);
				System.exit(1);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	private boolean done() {
		synchronized (lock) {
			return doneGame;
		}
	}



	private static int Xsize;
	private static int Ysize;
	private static JFrame frame;
	private static JFrame frame1;
	private static Boom bmain;
	private static Vector<SingleAgent> agentsVect = new Vector<SingleAgent>();

	/**
	 * This procedure parses the message which was accepted from the client
	 * 
	 * @param in - a message to be parsed by the server
	 * @return - a message to be sent as a feedback to the client.
	 */


	public static String parseInput(String in){
		String inn =in.trim();
		String feedBack=""; 
		StringTokenizer st = new StringTokenizer(inn);
		if (st.hasMoreTokens()) {
			String command = st.nextToken();

			/*if (command.equals("Stop")) return;*/
			if (command.compareTo("Board")==0){ //parse board
				Xsize = Integer.parseInt(st.nextToken());
				Ysize = Integer.parseInt(st.nextToken());
				frame = new JFrame("Board");

				//create a frame for the crawler window applet
				bmain = new Boom();
				frame.add(bmain,BorderLayout.CENTER);
				frame.setSize(Xsize*34,Ysize*3);
				frame.setLocation(20,20);
				bmain.init(Xsize,Ysize);
				bmain.start();
				frame.setVisible(true);
				frame.setAlwaysOnTop(true);

				frame.addWindowListener(new WindowAdapter()
				{
					public void windowClosing(WindowEvent e)
					{
						System.exit(0);
					}
				});
				feedBack="Board Done!";
			}
			else if(command.compareTo("Walls")==0){
				while(st.hasMoreTokens()){
					int cell = Integer.parseInt(st.nextToken());
					bmain.setWall(cell-1);
				}
				frame.pack();
				feedBack="Walls Done!";
			}
			else if(command.compareTo("Icy")==0){
				while(st.hasMoreTokens()){
					int cell = Integer.parseInt(st.nextToken());
					bmain.setIcyPatch(cell-1);
				}
				frame.pack();
				feedBack="Walls Done!";
			}
			else if(command.compareTo("Flags")==0){
				while(st.hasMoreTokens()){
					int cell = Integer.parseInt(st.nextToken());
					bmain.setFlag(cell-1);
				}
				feedBack="Flags Done!";
			}
			else if(command.compareTo("FlagsRemove")==0){
				while(st.hasMoreTokens()){
					int cell = Integer.parseInt(st.nextToken());
					bmain.deleteContent(cell-1);
					Toolkit.getDefaultToolkit().beep();
				}
				feedBack="Flags Removed!";
			}
			else if(command.compareTo("Agent")==0){

				String name = st.nextToken();
				String color = st.nextToken();
				String  orientation= st.nextToken();
				int cell = ((Integer.parseInt(st.nextToken()))-1);

				SingleAgent agent1 = new SingleAgent(name,color,orientation,cell,Xsize,Ysize);
				bmain.setAgent(agent1);
				agentsVect.addElement(agent1);
				feedBack="Agent Done!";
			}
			else if(command.compareTo("MoveAgent")==0 || command.compareTo("MoveAgentFromIce")==0){
				String agentName = st.nextToken();
				boolean found = false;
				int i=0;
				for (i=0;i<agentsVect.size() && !found;i++){
					SingleAgent tmp = ((SingleAgent)agentsVect.elementAt(i));
					if(agentName.compareToIgnoreCase(tmp.getName())==0){
						found = true;
						String move = st.nextToken();
						//added by ika
						if (command.compareTo("MoveAgent") == 0)
							bmain.deleteContent(tmp.getLocation());
						else if( command.compareTo("MoveAgentFromIce") == 0 )
							bmain.deleteContentFromIce(tmp.getLocation());
						if(move.compareToIgnoreCase("RIGHT") == 0){
							tmp.setLocation(tmp.getLocation()+1);
						}
						else if(move.compareToIgnoreCase("LEFT") == 0){
							tmp.setLocation(tmp.getLocation()-1);
						}
						else if(move.compareToIgnoreCase("UP") == 0){
							tmp.setLocation(tmp.getLocation()-tmp.getBoardXSize());
						}
						else if(move.compareToIgnoreCase("DOWN") == 0){
							tmp.setLocation(tmp.getLocation()+tmp.getBoardXSize());
						}
						else if(move.compareToIgnoreCase("SHOOT") == 0){
							tmp.setLocation(tmp.getLocation());
						}
						else{
							feedBack="Unknown move !!!";
						}
						bmain.setAgent(tmp);
					}
				}
				if(i >= agentsVect.size() && !found)
					feedBack="Agent not Found !!!";
			} else if (command.compareTo("MakeCamelDead") == 0){
				int cell = Integer.parseInt(st.nextToken());
				bmain.makeCamelDead(cell-1);
			}

			else{
				feedBack="Unknown command";
			}
		}	
		return feedBack;	
	}


	/**
	 * This is the main of the server application	
	 * 
	 * @param args
	 * @throws IOException
	 */



	public static boolean stopPlease = false;

	public static void main(String [] args) throws IOException 
	{	
		DatagramSocket serverSocket = new DatagramSocket(9876); 
		Debug.println("Server is on");

		while(! stopPlease ) 
		{ 
			byte[] receiveData = new byte[1024]; 
			byte[] sendData  = new byte[1024]; 
			DatagramPacket receivePacket = 
				new DatagramPacket(receiveData, receiveData.length); 
			serverSocket.receive(receivePacket); 
			String sentence = new String(receivePacket.getData());
			sentence=parseInput(sentence);

			InetAddress IPAddress = receivePacket.getAddress(); 

			int port = receivePacket.getPort(); 

			String capitalizedSentence = sentence.toUpperCase(); 

			sendData = capitalizedSentence.getBytes(); 

			DatagramPacket sendPacket = 
				new DatagramPacket(sendData, sendData.length, IPAddress, 
						port); 

			serverSocket.send(sendPacket); 
		}
	}
}

